package com.bite.job.handler;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.bit.common.redis.service.RedisService;
import com.bite.common.core.constants.CacheConstants;
import com.bite.job.domain.question.Question;
import com.bite.job.domain.question.vo.QuestionHotVO;
import com.bite.job.domain.user.vo.QuestionCountVO;
import com.bite.job.mapper.question.QuestionMapper;
import com.bite.job.mapper.user.UserSubmitMapper;
import com.github.pagehelper.PageHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.*;

@Slf4j
@Component
public class QuestionXxlJobHandler {

    @Value("${question.hot.queryCount:5}")
    private Integer hotQueryCount;

    @Value("${question.hot.submitWeight:20}")
    private Integer submitWeight;

    @Autowired
    private QuestionMapper questionMapper;

    @Autowired
    private UserSubmitMapper userSubmitMapper;

    @Autowired
    private RedisService redisService;


    @XxlJob("questionHotHandler")
    public void questionHotHandler() {
        // 先获取到今日的用户答题记录
        Map<Long, Long> questionCountMap = getQuestionCountMap();
        if (CollectionUtil.isEmpty(questionCountMap)) return;
        // 获取问题热度信息
        List<Question> questionList = getQuestionHot(questionCountMap);
        // 更新信息
        updateQuestion(questionList);
    }

    private void updateQuestion(List<Question> questionList) {
        // 更新MySQL
        questionMapper.batchUpdate(questionList);
        // 更新Redis
        // 获取更新后的数据
        PageHelper.startPage(1, hotQueryCount);
        List<Question> updateQuestionList = questionMapper.selectList(new LambdaQueryWrapper<Question>()
                .select(Question::getTitle, Question::getQuestionId, Question::getDifficulty)
                .orderByDesc(Question::getQuestionHot));
        String hotListKey = getHotListKey();
        redisService.deleteObject(hotListKey);
        List<Long> questionIdList = updateQuestionList.stream().map(Question::getQuestionId).toList();
        redisService.rightPushAll(hotListKey, questionIdList);

        Map<String, QuestionHotVO> questionHotVOMap = new HashMap<>();
        for (Question question : updateQuestionList) {
            QuestionHotVO questionHotVO = new QuestionHotVO();
            BeanUtil.copyProperties(question, questionHotVO);
            questionHotVOMap.put(getHotDetailKey(question.getQuestionId()), questionHotVO);
        }
        redisService.multiSet(questionHotVOMap);
    }

    private List<Question> getQuestionHot(Map<Long, Long> questionCountMap) {
        Set<Long> questionIdSet = questionCountMap.keySet();
        List<Question> questionList = questionMapper.selectList(new LambdaQueryWrapper<Question>()
                .select(Question::getQuestionId, Question::getQuestionHot)
                .in(Question::getQuestionId, questionIdSet));

        for (Question question : questionList) {
            Long questionId = question.getQuestionId();
            question.setQuestionHot(question.getQuestionHot() + questionCountMap.get(questionId) * submitWeight);
        }
        return questionList;
    }

    private Map<Long, Long> getQuestionCountMap() {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime minusDays = now.minusDays(1);
        List<QuestionCountVO> questionCountVOS = userSubmitMapper.selectCountGroupByUser(minusDays, now);
        Map<Long, Long> map = new HashMap<>();
        for (QuestionCountVO questionCountVO : questionCountVOS) {
            map.put(questionCountVO.getQuestionId(), questionCountVO.getCount());
        }
        return map;
    }

    private String getHotListKey() {
        return CacheConstants.QUESTION_HOT_LIST;
    }

    private String getHotDetailKey(Long questionId) {
        return CacheConstants.QUESTION_HOT_DETAIL + questionId;
    }
}
